package com.binarycube.webserver.datasource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import javax.xml.xpath.XPathExpressionException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import com.binarycube.webserver.config.DatasourceConfig;
/**
 * A data source for consuming data from a web service.
 * The data can be formatted as XML or as JSON, as specified in the config.
 * @author chris
 *
 */
public class WebServiceDataSource extends AbstractDataSource implements IDataSource{

	static Logger log = Logger.getLogger(WebServiceDataSource.class.getName());
	
	private static String FORMAT_XML = "xml";
	private static String FORMAT_JSON = "json";
	
	String url;
	String format;
	String path;
	
	
	public List<Record> doQuery() {
		validateParams();
		//perform the request
		try {
			
			URL u = new URL(url);
			
		    InputStream is = u.openConnection().getInputStream();
	
		    BufferedReader reader = new BufferedReader( new InputStreamReader( is )  );
		    //Assume data is not going to be that large
		    StringBuilder buffer = new StringBuilder();
		    String line = null;
		    while( ( line = reader.readLine() ) != null )  {
		       buffer.append(line);
		    }
		    reader.close();
		    
		    if (format.equals(FORMAT_JSON)) {
		    	//Split the path an get the target object(s)
		    	JSONObject json = JSONObject.fromObject(buffer.toString());
		    	String[] pathItems = path.split("\\.");
		    	for (int i=0; i< (pathItems.length -1) ; i++) {
		    		json = json.getJSONObject(pathItems[i]);
		    	}
		    	
		    	Object x = json.getJSONArray(pathItems[pathItems.length -1]);
		    	
		    	if (x instanceof JSONArray) {
		    		JSONArray jsonArray = (JSONArray)x;
		    		for (int i =0; i < jsonArray.size(); i++) {
			    		Record r = Record.JSONRecord();
			    		r.set(jsonArray.getJSONObject(i));
			    		_records.add(r);
		    		}
		    	}
		    	
		    } else {
		    	_records = XMLDataSource.toJSONRecords(new StringReader(buffer.toString()), path);
		    	
		    }
		    
		} catch (IOException | XPathExpressionException e) {
			log.error("Error querying Webservice Datasource: " + _config.getName(), e);
		}
		
		return _records;
	}
	
	
	public void configure(DatasourceConfig config) {
		super.configure(config);
	
		url = _config.getProperty("url");
		format = _config.getProperty("format");
		path = _config.getProperty("path");
	
		if (format.toLowerCase().equals(FORMAT_XML)) format = FORMAT_XML;
		else format = FORMAT_JSON;
		
		/* Test the connection */
		try {
			URL u = new URL(url);
			URLConnection conn = u.openConnection();
			conn.connect();
		} catch (IOException e) {
			log.error("Error connecting to Webservice Datasource: " + _config.getName(), e);
		}
		
	}




}
